﻿using System;
using System.Collections.Generic;
using eBay.Service.Call;
using eBay.Service.Core.Sdk;
using eBay.Service.Core.Soap;
using OigSync.Domain.Utility;
using OigSync.Infrastructure.Api;

namespace OigSync.Domain.Api
{
    /*
     * 下载订单API,有遗漏,需用GetTransaction对比确认遗漏订单
     */
    public class GetOrdersApi : ApiBase
    {
        /*
         * Constructor
         */
        public GetOrdersApi(String token) : base(token) {
            
        }

        /*
         * 重载ApiBase.Execute函数
         */
        public override void Execute()
        {
            if (!(this.Setting is GetOrdersApiSetting))
                throw new ApiSettingTypeErrorException();

            GetOrdersApiSetting setting = this.Setting as GetOrdersApiSetting;

            GetOrdersCall call = new GetOrdersCall(Context);

            call.DetailLevelList.Add(DetailLevelCodeType.ReturnAll);
            call.IncludeFinalValueFee = setting.IncludeFinalValueFee;
            call.ModTimeTo = setting.TimeFrom;
            call.ModTimeTo = setting.TimeTo;
            call.OrderRole = TradingRoleCodeType.Seller;
            call.OrderStatus = OrderStatusCodeType.All;
            call.Timeout = setting.Timeout;

            PaginationType pagination = new PaginationType();
            pagination.EntriesPerPage = setting.EntriesPerPage;
            pagination.PageNumber = setting.PageNumber;
            call.Pagination = pagination;

            CallRetry retry = new CallRetry();
            retry.DelayTime = setting.RetryDelayTime;
            retry.MaximumRetries = setting.RetryMaximumRetries;
            call.CallRetry = retry;

            try
            {
                call.Execute();
                GetApiResult(call);
            }
            catch (System.Exception ex)
            {
                if (ex.InnerException is System.Net.WebException &&
                    (((System.Net.WebException)ex.InnerException).Status == System.Net.WebExceptionStatus.Timeout ||
                    ((System.Net.WebException)ex.InnerException).Status == System.Net.WebExceptionStatus.KeepAliveFailure ||
                    ((System.Net.WebException)ex.InnerException).Status == System.Net.WebExceptionStatus.ReceiveFailure))
                {
                    Execute();
                }
            }
        }

        /*
         * 获取API结果
         */
        private void GetApiResult(GetOrdersCall call)
        {
            GetOrderApiResult result = new GetOrderApiResult();

            result.HasMoreOrders = call.HasMoreOrders;
            result.TotalNumberOfEntries = call.PaginationResult.TotalNumberOfEntries;
            result.TotalNumberOfPages = call.PaginationResult.TotalNumberOfPages;
            result.OrderList = new List<OigSync.Model.Order>();

            foreach (OrderType apiOrder in call.OrderList)
            {
                OigSync.Model.Order order = new OigSync.Model.Order();

                order.OrderSalesRecordNumber = (apiOrder.ShippingDetails == null) ? String.Empty : apiOrder.ShippingDetails.SellingManagerSalesRecordNumber.ToString();
                order.OrderID = apiOrder.OrderID;
                order.UserID = apiOrder.BuyerUserID;
                order.BuyerFullName = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.Name;
                order.BuyerAddress1 = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.Street1;
                order.BuyerAddress2 = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.Street2;
                order.BuyerCity = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.CityName;
                order.BuyerCounty = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.County;
                order.BuyerState = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.StateOrProvince;
                order.BuyerCountry = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.Country.ToString();
                order.BuyerPhone = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.Phone;
                order.BuyerPostcode = apiOrder.ShippingAddress == null ? String.Empty : apiOrder.ShippingAddress.PostalCode;
                order.PostageAndPackageCost = (apiOrder.ShippingServiceSelected == null || apiOrder.ShippingServiceSelected.ShippingServiceCost == null) ? 0 : apiOrder.ShippingServiceSelected.ShippingServiceCost.Value;
                order.Insurance = apiOrder.ShippingDetails.InsuranceFee == null ? 0d : apiOrder.ShippingDetails.InsuranceFee.Value;
                order.PaymentMethod = apiOrder.CheckoutStatus == null ? String.Empty : apiOrder.CheckoutStatus.PaymentMethod.ToString();
                order.eBayPaymentStatus = apiOrder.CheckoutStatus == null ? String.Empty : apiOrder.CheckoutStatus.eBayPaymentStatus.ToString();
                order.PaidonDate = DateTimeHelper.GetLegalDatetime(apiOrder.PaidTime);
                order.CompleteStatus = apiOrder.OrderStatus.ToString();
                order.CheckoutStatus = apiOrder.CheckoutStatus == null ? String.Empty : apiOrder.CheckoutStatus.Status.ToString();
                order.LastTimeModified = apiOrder.CheckoutStatus == null ? DateTimeHelper.MinDateTime : DateTimeHelper.GetLegalDatetime(apiOrder.CheckoutStatus.LastModifiedTime);
                order.PostageService = apiOrder.ShippingServiceSelected == null ? String.Empty : apiOrder.ShippingServiceSelected.ShippingService;

                order.Transactions = new List<OigSync.Model.Transaction>();
                foreach(TransactionType apiTransaction in apiOrder.TransactionArray) {
                    OigSync.Model.Transaction transaction = new OigSync.Model.Transaction();

                    transaction.OrderLineItemID = apiTransaction.OrderLineItemID;
                    transaction.SalesRecordNumber = apiTransaction.ShippingDetails == null ? String.Empty : apiTransaction.ShippingDetails.SellingManagerSalesRecordNumber.ToString();
                    transaction.ItemID = apiTransaction.Item == null ? String.Empty : apiTransaction.Item.ItemID;
                    transaction.TransactionID = apiTransaction.TransactionID;
                    transaction.BuyerEmail = apiTransaction.Buyer == null ? String.Empty : apiTransaction.Buyer.Email;
                    transaction.ItemTitle = apiTransaction.Item == null ? String.Empty : apiTransaction.Item.Title;
                    transaction.Quantity = apiTransaction.QuantityPurchased;
                    transaction.SalePrice = apiTransaction.TransactionPrice == null ? 0 : apiTransaction.TransactionPrice.Value;
                    transaction.FinalValueFee = apiTransaction.FinalValueFee == null ? 0d : apiTransaction.FinalValueFee.Value;
                    transaction.InvoiceDate = DateTimeHelper.GetLegalDatetime(apiTransaction.InvoiceSentTime);
                    transaction.IncludedVATRate = apiTransaction.Buyer == null ? "" : apiTransaction.Buyer.VATStatus.ToString();
                    transaction.SaleDate = DateTimeHelper.GetLegalDatetime(apiTransaction.CreatedDate);
                    transaction.CustomLable = apiTransaction.Item == null ? String.Empty : apiTransaction.Item.SKU;
                    transaction.PrivateNotes = apiTransaction.Item == null ? String.Empty : apiTransaction.Item.PrivateNotes;
                    transaction.VariationSKU = apiTransaction.Variation == null ? String.Empty : apiTransaction.Variation.SKU;
                    transaction.VariationTitle = apiTransaction.Variation == null ? String.Empty : apiTransaction.Variation.VariationTitle;
                    transaction.VariationViewItemURL = apiTransaction.Variation == null ? String.Empty : apiTransaction.Variation.VariationViewItemURL;
                    transaction.BuyerSelectedShipping = apiTransaction.Status == null ? String.Empty : apiTransaction.Status.BuyerSelectedShipping.ToString();
                    transaction.FeedbackScore = apiTransaction.Buyer == null ? 0 : apiTransaction.Buyer.FeedbackScore;
                    transaction.PositiveFeedbackPercent = apiTransaction.Buyer == null ? 0 : apiTransaction.Buyer.PositiveFeedbackPercent;
                    transaction.Platform = apiTransaction.Platform.ToString();
                    transaction.Site = apiTransaction.Item.Site.ToString();

                    if (apiTransaction.Variation != null && apiTransaction.Variation.VariationSpecifics != null)
                    {
                        transaction.Variations = new List<OigSync.Model.Variation>();
                        
                        foreach(NameValueListType pair in apiTransaction.Variation.VariationSpecifics) {
                            OigSync.Model.Variation variation = new OigSync.Model.Variation();

                            variation.VariationSKU = transaction.VariationSKU;
                            variation.VariationName = pair.Name;
                            variation.VariationValue = String.Join(",", pair.Value.ToArray());

                            transaction.Variations.Add(variation);
                        }
                    }

                    order.Transactions.Add(transaction);
                }

                order.PayPalTransactions = new List<OigSync.Model.PayPalTransaction>();

                foreach (ExternalTransactionType apiPayPalTransaction in apiOrder.ExternalTransaction)
                {
                    OigSync.Model.PayPalTransaction paypalTransaction = new OigSync.Model.PayPalTransaction();

                    paypalTransaction.TransactionID = apiPayPalTransaction.ExternalTransactionID;
                    paypalTransaction.ExternalTransactionTime = apiPayPalTransaction.ExternalTransactionTime;
                    paypalTransaction.FeeOrCreditAmount = apiPayPalTransaction.FeeOrCreditAmount == null ? 0d : apiPayPalTransaction.FeeOrCreditAmount.Value;
                    paypalTransaction.PaymentOrRefundAmount = apiPayPalTransaction.PaymentOrRefundAmount == null ? 0d : apiPayPalTransaction.PaymentOrRefundAmount.Value;

                    order.PayPalTransactions.Add(paypalTransaction);
                }

                order.ImportDate = DateTime.Now;

                result.OrderList.Add(order);
            }
        }
    }
}
